from gettext import gettext as _
import logging
from typing import Any
from blueman.bluemantyping import ObjectPath

from gi.repository import GLib

from blueman.bluez.Network import AnyNetwork, Network
from blueman.gui.Notification import Notification
from blueman.plugins.AppletPlugin import AppletPlugin
from blueman.main.DBusProxies import Mechanism


class DhcpClient(AppletPlugin):
    __description__ = _("Provides a basic dhcp client for Bluetooth PAN connections.")
    __icon__ = "network-workgroup-symbolic"
    __author__ = "Walmis"

    _any_network = None

    def on_load(self) -> None:
        self._any_network = AnyNetwork()
        self._any_network.connect_signal('property-changed', self._on_network_prop_changed)

        self.querying: list[str] = []

        self._add_dbus_method("DhcpClient", ("s",), "", self.dhcp_acquire)

    def on_unload(self) -> None:
        del self._any_network

    def _on_network_prop_changed(self, _network: AnyNetwork, key: str, value: Any, object_path: ObjectPath) -> None:
        if key == "Interface":
            if value != "":
                self.dhcp_acquire(object_path)

    def dhcp_acquire(self, object_path: ObjectPath) -> None:
        device = Network(obj_path=object_path)["Interface"]

        if device not in self.querying:
            self.querying.append(device)
        else:
            return

        if device != "":
            def reply(_obj: Mechanism, result: str, _user_data: None) -> None:
                logging.info(result)
                Notification(_("Bluetooth Network"),
                             _("Interface %(0)s bound to IP address %(1)s") % {"0": device, "1": result},
                             icon_name="network-workgroup").show()

                self.querying.remove(device)

            def err(_obj: Mechanism, result: GLib.Error, _user_data: None) -> None:
                logging.warning(result)
                Notification(_("Bluetooth Network"), _("Failed to obtain an IP address on %s") % device,
                             icon_name="network-workgroup").show()

                self.querying.remove(device)

            Notification(_("Bluetooth Network"), _("Trying to obtain an IP address on %s\nPlease wait…" % device),
                         icon_name="network-workgroup").show()

            m = Mechanism()
            m.DhcpClient('(s)', object_path, result_handler=reply, error_handler=err, timeout=120 * 1000)
